﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Valentia.Kinection.Configuration;
using System.Net;
using System.Text.RegularExpressions;
using System.IO;

namespace Valentia.Kinection.Configuration.Manager
{
    /// <summary>
    /// User control used to view and update service settings
    /// </summary>
    public partial class ServiceSettings : UserControl
    {
        #region Constructor

        /// <summary>
        /// Constructor.
        /// </summary>
        public ServiceSettings()
        {
            InitializeComponent();
            FillDropdown();
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Load service settings from application database 
        /// and shows on form
        /// </summary>
        public void LoadServiceSettings()
        {
            List<ServiceSetting> serviceSettings = ConfigurationHelper.GetServiceSettings();

            if (serviceSettings != null && serviceSettings.Count > 0)
            {
                txtChannelName.Text = serviceSettings[0].RemotingChannelName;
                numRemotingServerPort.Value = serviceSettings[0].RemotingServerPort;
                cboWebSocketServerIP.Text = serviceSettings[0].WebSocketServerIP;
                numWebSocketServerPort.Value = serviceSettings[0].WebSocketServerPort;
                cboSecureWSSIP.Text = serviceSettings[0].SecureWebSocketServerIP;
                numSecureWebSocketServerPort.Value = serviceSettings[0].SecureWebSocketServerPort;
                txtSecureWebSocketServerCertificateURL.Text = serviceSettings[0].ServerWebScoketCertificate;
                chkRunSecureSocketServer.Checked = serviceSettings[0].RunSecureSocketServer;
                txtLogDirectory.Text = serviceSettings[0].LogDirectory;
                chkLogEnabled.Checked = serviceSettings[0].IsLoggingEnabled;
            }
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Fills drop down controls with default values
        /// </summary>
        private void FillDropdown()
        {
            IPAddress[] ipAddresses = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
            foreach (IPAddress address in ipAddresses)
            {
                if (address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) continue;
                if (address.ToString().Equals("0.0.0.0") || address.ToString().Equals("127.0.0.1")) continue;

                cboWebSocketServerIP.Items.Add(address.ToString());
                cboSecureWSSIP.Items.Add(address.ToString());
            }

            cboWebSocketServerIP.Items.Insert(0, "Any"); //0.0.0.0
            cboWebSocketServerIP.Items.Insert(1, "Local"); //127.0.0.1

            cboWebSocketServerIP.SelectedIndex = 0;

            cboSecureWSSIP.Items.Insert(0, "Any"); //0.0.0.0
            cboSecureWSSIP.Items.Insert(1, "Local"); //127.0.0.1

            cboSecureWSSIP.SelectedIndex = 0;
        }

        /// <summary>
        /// Validates the service settings data to be saved
        /// </summary>
        /// <returns>True/False : service settings data is valid</returns>
        private bool IsValidData()
        {
            errProvider.Clear();
            if (txtChannelName.Text.Trim().Equals(string.Empty))
            {
                errProvider.SetError(txtChannelName, "Please provide channel name");
                txtChannelName.Focus();
                return false;
            }

            if (!Regex.Match(txtChannelName.Text, "^[a-zA-Z.]+$").Success)
            {
                errProvider.SetError(txtChannelName, "Channel name must be of alphabets, spaces are not allowed");
                txtChannelName.Focus();
                return false;
            }

            if (txtLogDirectory.Text.Length > 0)
            {
                if (!Directory.Exists(txtLogDirectory.Text))
                {
                    errProvider.SetError(btnSelectLogDirectory, "Directory does not exists");
                    btnSelectLogDirectory.Focus();
                    return false;
                }
            }

            if (txtSecureWebSocketServerCertificateURL.Text.Length > 0)
            {
                if (!File.Exists(txtSecureWebSocketServerCertificateURL.Text))
                {
                    errProvider.SetError(btnSelectCertificateFile, "File does not exists");
                    btnSelectCertificateFile.Focus();
                    return false;
                }
            }

            return true;
        }
        
        #endregion

        #region Form control events

        /// <summary>
        /// Occurs when select log directory button clicked
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Event Args</param>
        private void btnSelectLogDirectory_Click(object sender, EventArgs e)
        {
            if (folderBrowser.ShowDialog() == DialogResult.OK)
            {
                txtLogDirectory.Text = folderBrowser.SelectedPath;
            }
        }

        /// <summary>
        /// Occurs when select Certificate file button clicked
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Event Args</param>
        private void btnSelectCertificateFile_Click(object sender, EventArgs e)
        {
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                txtSecureWebSocketServerCertificateURL.Text = openFileDialog.FileName;
            }
        }

        /// <summary>
        /// Occurs when Save/Update button clicked
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Event Args</param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            if (!IsValidData())
            {
                return;
            }
            ConfigurationHelper.SaveServiceSettings(Convert.ToInt32(numRemotingServerPort.Value)
                , txtChannelName.Text, cboWebSocketServerIP.Text, Convert.ToInt32(numWebSocketServerPort.Value)
                , cboSecureWSSIP.Text, Convert.ToInt32(numSecureWebSocketServerPort.Value)
                , chkRunSecureSocketServer.Checked, txtSecureWebSocketServerCertificateURL.Text
                , txtLogDirectory.Text, chkLogEnabled.Checked);

            MessageBox.Show("Settings saved successfully.", Program.ApplicationName
                        , MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        /// <summary>
        /// Occurs when reset button clicked
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Event Args</param>
        private void btnReset_Click(object sender, EventArgs e)
        {
            LoadServiceSettings();
        }

        #endregion
    }
}
